package BergBrains::PerlDocViewer;
use Dancer ':syntax';
use Dancer::Plugin::Cache::CHI;
use Dancer::Plugin::Ajax;
use Log::Log4perl qw(get_logger);
use Params::Validate qw(:all);
use Data::Dumper;
use Pod::ProjectDocs;
use Pod::Simple::HTML;
use Tree::Builder;
use Carp qw(confess);

use CGIMan::FileList;

our $VERSION = '0.1';

get '/' => sub {
    ## This is from the default
    template 'index';
};

get '/test/:book/' => sub {

    #get '/test' => sub {
    my $log = get_logger('test');
    cache_clear();

    set layout => 'left_nav';
    my @rows = get_rows( params->{book} );

    #$log->trace( "Row dumper: " . Dumper( \@rows ) );

    #template 'file_list', { file_list => \@rows };
    template 'file_list', { file_list => \@rows };
};

sub root_dirs {
    my $log = get_logger('root_dirs');
    my $book = shift || confess("No book.  Need book.");

    my $root_dirs = config->{books}{$book}{paths};
    $log->info( "Paths: " . Dumper($root_dirs) );    # if $log->is_trace;
    return wantarray ? @$root_dirs : $root_dirs;
}

sub get_rows {
    my $book = shift || die "No book.  Need book 'book': " . scalar caller;
    my $log = get_logger('get_rows');

    my $file_list_obj =
      CGIMan::FileList->new( pod_dirs => scalar root_dirs($book) );
    $log->trace( "FileList: " . Dumper($file_list_obj) );
    my @rows;

    #foreach my $file ( (@{$file_list_obj->file_list})[0..3]) {
    foreach my $file ( @{ $file_list_obj->file_list } ) {
        push @rows, $file;
    }

    $log->debug( "File count: " . @rows );
    return wantarray ? @rows : \@rows;
}

get '/list/:book' => sub {
    my $log = get_logger('main_list');

    my @rows = get_rows( params->{book} );
    template 'file_list', { file_list => \@rows };
};

=head2 get_tree

This runmode retrieves a CGIMan::FileList object for the diretories
specified in the 'root_dir' parameter and returns a JSON
representation of this tree suitable for use in the jqtree Javascript
tree widget.

here are the steps:

=over

=item First, we get the file list

=item Next, convert the FileList to a tree based on namespace as seen in the namespace_path

=item Then we convert that tree into the data structure that jsqtree can digest.

=back

=cut

get '/tree/:book/' => sub {

    #get '/tree' => sub {
    my $book = 'dev';                #params->{book};
    my $log  = get_logger('tree');

    # Convert File::List to tree
    # Build the tree
    cache_clear();
    my $file_list = cache_get('file_list');

    if ( !$file_list ) {
        $log->debug("Getting file list");
        $file_list = CGIMan::FileList->new( pod_dirs => root_dirs($book) );

        #die "xxx";
        $log->info( "Dumper file list: " . Dumper($file_list) );
        cache_set( 'file_list', $file_list );
    }
    else {
        $log->debug("Already have file list");
    }

    # Convert tree to jqtree format data structure
    my $tb = Tree::Builder->new();
    foreach my $file ( @{ $file_list->file_list } ) {

        #warn "File: " . $file->file_name;
        #warn "Namespace: " . $file->package_name;
        $tb->add( $file->namespace_path );
        if ( $tb->error ) {
            warn( 'error: ' . $file->error . ":" . $file->errorString );
        }
    }

    my %tree = $tb->getTree;

    #    $log->trace( "XXX" . Dumper($tb)) if $log->is_trace;
    #    $log->trace("YYY" . Dumper( \%tree )) if $log->is_trace;

    my $jsq_tree = process_tree_node( node => \%tree, );

    return $jsq_tree;
};

=head2 process_tree_node

Recursively builds tree

=cut

sub process_tree_node {
    my %params = validate(
        @_,
        {
            node      => { type => HASHREF },
            namespace => {
                type     => SCALAR,
                optional => 1,
            },
        }
    );
    my @retval = [];

    #warn "Node dump: " . Dumper($params{node});

    my @children;

    # If it has children, add the 'children' array
    if ( keys %{ $params{node} } ) {

        #warn "Node has keys.";
        foreach my $child_name ( keys %{ $params{node} } ) {

            #warn "Processing node child '$child_name'";
            my $namespace = join( "/",
                ( $params{namespace} ? ( $params{namespace} ) : () ),
                $child_name );
            $namespace = '/' . $namespace unless $namespace =~ m|^/|;
            my %child;
            $child{namespace} = $namespace if $child{namespace};
            $child{label}     = $child_name;
            $child{id}        = $namespace;
            $child{children}  = process_tree_node(
                node      => $params{node}{$child_name},
                namespace => $namespace,
            );

            #warn "Child dump: " . Dumper(\%child);
            push @children, \%child;
        }
    }

    return wantarray ? @children : \@children;
}

=head2 clear_cache

Clears the file info cache.

=cut

get "/clear_cache" => sub {
    cache_clear;

    return {
        status => 'OK',
        msg    => 'Cache successfully cleared.',
    };
};

# http://moby:3000/render/pod/eb_file_set/?file=/home/mynaths/blestardis/fheh
get '/render/:type/:fileset/' => sub {
    my $log = get_logger('render');
    my $renderer = params->{type} || 'pod';

    $log->debug("Renderer: '$renderer'");

    my $file_set = params->{fileset} || 1;
    $log->debug( "File set: " . $file_set );
    my $prefix = '/usr/local/lib/perl/5.14.2';

    my $file = $prefix . '/'
      . 'Moose/Meta/Attribute/Native/Trait/Code.pm';    #params->{file};
    $log->debug("File: '$file'");

    if (1) {

        #q->param('full_path')        info("PATH: " . $file) );

        my $p = Pod::Simple::HTML->new;
        $p->index(1);
        $p->output_string( \my $html );
        eval { $p->parse_file($file); };

        if ($html) {
            return $html;
        }
        else {
            return "NO POD CONTENT FOUND for " . $file;
        }
    }
    else {
        my $pod_root = '/tmp/pod';
        my $pd       = Pod::ProjectDocs->new(
            outroot => $pod_root,
            libroot => '/home/eberg/work/CGIMan/lib/perl5/',
            title   => 'CGIMan',
        );

        my $file_name = join "/", $pod_root, basename($file);
        $file_name = $file;
        $log->debug("FILE NAME: '$file_name'");
        $pd->gen();
    }

};

true;
